package com.erp.freight.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.erp.freight.domain.*;
import com.erp.freight.domain.bo.ErpProductFreightBo;
import com.erp.freight.domain.vo.ErpProductFreightVo;
import com.erp.freight.mapper.*;
import com.erp.freight.service.IErpProductFreightService;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.web.oldPage.TableDataInfo;
import com.ruoyi.freight.api.domain.AeProductFreight;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import com.ruoyi.freight.api.domain.ErpProductExistingFreightRecord;
import java.math.BigDecimal;
import java.util.*;

/**
 * 运费试算模版（各物流公司运费格读取）Service业务层处理
 *
 * @author erp
 * @date 2023-06-23
 */
@RequiredArgsConstructor
@Service
public class ErpProductFreightServiceImpl implements IErpProductFreightService {

    private final ErpProductFreightMapper baseMapper;

    private final ErpProductFreightBaleMapper baleMapper;

    private final ErpProductFreightYanwenMapper yanwenMapper;

    private final ErpProductFreightCountryZoneMapper countryZoneMapper;

    private final ErpProductFreightEconomyMapper economyMapper;

	/**
	 * 查询运费试算模版（各物流公司运费格读取）
	 */
	@Override
	public ErpProductFreightVo queryById(Long id) {
		return baseMapper.selectVoById(id);
	}

	/**
	 * 查询运费试算模版（各物流公司运费格读取）列表
	 */
	@Override
	public TableDataInfo<ErpProductFreightVo> queryPageList(ErpProductFreightBo bo, PageQuery pageQuery) {
		LambdaQueryWrapper<ErpProductFreight> lqw = buildQueryWrapper(bo);
		Page<ErpProductFreightVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
		return TableDataInfo.build(result);
	}

	/**
	 * 查询运费试算模版（各物流公司运费格读取）列表
	 */
	@Override
	public List<ErpProductFreightVo> queryList(ErpProductFreightBo bo) {
		LambdaQueryWrapper<ErpProductFreight> lqw = buildQueryWrapper(bo);
		return baseMapper.selectVoList(lqw);
	}

	private LambdaQueryWrapper<ErpProductFreight> buildQueryWrapper(ErpProductFreightBo bo) {
		Map<String, Object> params = bo.getParams();
		LambdaQueryWrapper<ErpProductFreight> lqw = Wrappers.lambdaQuery();
		lqw.eq(StringUtils.isNotBlank(bo.getFreightType()), ErpProductFreight::getFreightType, bo.getFreightType());
		lqw.eq(StringUtils.isNotBlank(bo.getCountry()), ErpProductFreight::getCountry, bo.getCountry());
		lqw.eq(StringUtils.isNotBlank(bo.getCountryEn()), ErpProductFreight::getCountryEn, bo.getCountryEn());
		lqw.eq(StringUtils.isNotBlank(bo.getCountryCode()), ErpProductFreight::getCountryCode, bo.getCountryCode());
		lqw.eq(StringUtils.isNotBlank(bo.getWeight()), ErpProductFreight::getWeight, bo.getWeight());
		lqw.eq(bo.getFreight() != null, ErpProductFreight::getFreight, bo.getFreight());
		lqw.eq(bo.getRegistrationFee() != null, ErpProductFreight::getRegistrationFee, bo.getRegistrationFee());
		lqw.eq(bo.getPackageType() != null, ErpProductFreight::getPackageType, bo.getPackageType());
		lqw.eq(StringUtils.isNotBlank(bo.getRevision()), ErpProductFreight::getRevision, bo.getRevision());
		return lqw;
	}

	/**
	 * 新增运费试算模版（各物流公司运费格读取）
	 */
	@Override
	public Boolean insertByBo(ErpProductFreightBo bo) {
		ErpProductFreight add = BeanUtil.toBean(bo, ErpProductFreight.class);
		validEntityBeforeSave(add);
		boolean flag = baseMapper.insert(add) > 0;
		if (flag) {
			bo.setId(add.getId());
		}
		return flag;
	}

	/**
	 * 修改运费试算模版（各物流公司运费格读取）
	 */
	@Override
	public Boolean updateByBo(ErpProductFreightBo bo) {
		ErpProductFreight update = BeanUtil.toBean(bo, ErpProductFreight.class);
		validEntityBeforeSave(update);
		return baseMapper.updateById(update) > 0;
	}

	/**
	 * 保存前的数据校验
	 */
	private void validEntityBeforeSave(ErpProductFreight entity) {
		// TODO 做一些数据校验,如唯一约束
	}

    /**
     * 批量删除运费试算模版（各物流公司运费格读取）
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }



    @Override
    public Boolean judgeBaleProduct(ErpProductExistingFreightRecord erpProductExistingFreightRecord){
        /**
         * 大包(计泡)计重规则，实际重量与体积重取大值，（体积重 ：长(cm)*宽(cm)*高(cm)/8000）
         * 大包计费：包裹申报重量>2kg，或包裹实际重量>2kg，或包裹单边长度>60cm，或包裹长+宽+高>90cm
         */
        // 检查包裹重量
        if(new BigDecimal(erpProductExistingFreightRecord.getWeight()).compareTo(new BigDecimal("2000")) > 0){
            return true;
        }
        // 检查单边长度
        BigDecimal singleLength = new BigDecimal("60");
        if(new BigDecimal(erpProductExistingFreightRecord.getLength()).compareTo(singleLength) > 0
                || new BigDecimal(erpProductExistingFreightRecord.getWidth()).compareTo(singleLength) > 0
                || new BigDecimal(erpProductExistingFreightRecord.getHeight()).compareTo(singleLength) > 0 ){
            return true;
        }
        // 检查总长
        BigDecimal totalLength = new BigDecimal("90");
        if((new BigDecimal(erpProductExistingFreightRecord.getLength())
                .add(new BigDecimal(erpProductExistingFreightRecord.getWidth()))
                .add(new BigDecimal(erpProductExistingFreightRecord.getHeight()))).compareTo(totalLength) > 0){
            return true;
        }
        return false;
    }

	@Override
	public Boolean judgeBaleProduct(AeProductFreight aeProductFreight){
		/**
		 * 大包(计泡)计重规则，实际重量与体积重取大值，（体积重 ：长(cm)*宽(cm)*高(cm)/8000）
		 * 大包计费：包裹申报重量>2kg，或包裹实际重量>2kg，或包裹单边长度>60cm，或包裹长+宽+高>90cm
		 */
		// 检查包裹重量
		if(new BigDecimal(aeProductFreight.getWeight()).compareTo(new BigDecimal("2000")) > 0){
			return true;
		}
		// 检查单边长度
		BigDecimal singleLength = new BigDecimal("60");
		if(new BigDecimal(aeProductFreight.getLength()).compareTo(singleLength) > 0
				|| new BigDecimal(aeProductFreight.getWidth()).compareTo(singleLength) > 0
				|| new BigDecimal(aeProductFreight.getHeight()).compareTo(singleLength) > 0 ){
			return true;
		}
		// 检查总长
		BigDecimal totalLength = new BigDecimal("90");
		if((new BigDecimal(aeProductFreight.getLength())
				.add(new BigDecimal(aeProductFreight.getWidth()))
				.add(new BigDecimal(aeProductFreight.getHeight()))).compareTo(totalLength) > 0){
			return true;
		}
		return false;
	}

	@Override
	public BigDecimal calculateFreightByCaiNiao(String areaNo, String skuWeight, String skuWidth, String skuHeight,
			String skuLength, String productAttribute) {

		if (!productAttribute.equals("0"))
			productAttribute = "1";

		ErpProductExistingFreightRecord erpProductExistingFreightRecord = new ErpProductExistingFreightRecord();
		erpProductExistingFreightRecord.setCountry(areaNo);
		erpProductExistingFreightRecord.setWeight(skuWeight);
		erpProductExistingFreightRecord.setHeight(skuHeight);
		erpProductExistingFreightRecord.setWidth(skuWidth);
		erpProductExistingFreightRecord.setLength(skuLength);
		erpProductExistingFreightRecord.setType(Integer.valueOf(productAttribute));
		BigDecimal calculateFreightByCaiNiao = calculateFreightByCaiNiao(erpProductExistingFreightRecord);
		return calculateFreightByCaiNiao;
	}

	/**
	 * 该方法已废弃，勿更新！！！！！！！！！！新方法为IErpCommonProductFreightService
	 *
	 * @param erpProductExistingFreightRecord
	 * @return
	 */
	@Override
	public BigDecimal calculateFreightByCaiNiao(ErpProductExistingFreightRecord erpProductExistingFreightRecord) {

		Boolean isBale = judgeBaleProduct(erpProductExistingFreightRecord);

		// 默认国大包是否计泡
		boolean isBubbleFlg = false;

		if (isBale) {
			/** 大包货物计算流程 **/
			// 优先获取大包专线到获取目的国的计价标准
			ErpProductFreightBale freightBale = baleMapper
					.getFreightTemplateByCountryCode(erpProductExistingFreightRecord.getCountry(), "菜鸟大包专线");
			if (freightBale == null) {
				// 不支持，获取标准物流的大包
				freightBale = baleMapper.getFreightTemplateByCountryCode(erpProductExistingFreightRecord.getCountry(), "菜鸟无忧物流-标准");
				if (freightBale == null) {
					// 不支持，获取标准物流的AL(阿尔巴尼亚)的大包
					freightBale = baleMapper.getFreightTemplateByCountryCode("AL", "菜鸟无忧物流-标准");
					// 默认计泡
					isBubbleFlg = true;
				}
			}
			// 货物实际重量
			BigDecimal packageWeight = new BigDecimal(erpProductExistingFreightRecord.getWeight());
			// 1、判断该目的国是否计泡，主要是判断是否需要更改货物的最终重量
			if (freightBale.getBubbleType().intValue() == 1
					|| (isBubbleFlg && freightBale.getBubbleType().intValue() == 0)) {
				// 计泡，则计算体积重 ：长(cm)*宽(cm)*高(cm)/8000
				BigDecimal volumeWeight = new BigDecimal(erpProductExistingFreightRecord.getLength())
						.multiply(new BigDecimal(erpProductExistingFreightRecord.getWidth()))
						.multiply(new BigDecimal(erpProductExistingFreightRecord.getHeight())).divide(new BigDecimal("8000"));
				// 按g进行比较
				if (packageWeight.compareTo(volumeWeight.multiply(new BigDecimal("1000"))) < 0) {
					// 泡物，取体积重的大值
					packageWeight = volumeWeight.multiply(new BigDecimal("1000"));
				}
			}
			// 判断是否超重
//            if(packageWeight.compareTo(new BigDecimal(freightBale.getLimitWeight())) > 0){
			// 大包超重 区域试算 不考虑超重
//                return null;
//            }

			// 2、判断该目的国是否有续重
			if (freightBale.getContinuationWeight().equals("0")) {
				// 无续重，则1g起重
				BigDecimal freight = freightBale.getFirstFreight().divide(new BigDecimal(freightBale.getFirstWeight()))
						.multiply(packageWeight);
				// 总费用为运费+挂号费
				return freight.add(freightBale.getRegistrationFee());
			} else {
				/**
				 * 有续重， 1、重量未超起重 2、超起重，未超续重 3、超起重，超续重，续重按整数计算
				 */
				// 判断是否有挂号费
				BigDecimal registrationFee = freightBale.getRegistrationFee() == null ? new BigDecimal("0")
						: freightBale.getRegistrationFee();
				if (packageWeight.compareTo(new BigDecimal(freightBale.getFirstWeight())) <= 0) {
					// 未超起重
					return freightBale.getFirstFreight().add(registrationFee);
				} else {
					// 超起重，获取剩余重量
					BigDecimal remainingWeight = packageWeight.subtract(new BigDecimal(freightBale.getFirstWeight()));
					// 根据续重，向上取整
					BigDecimal multiple = remainingWeight.divide(new BigDecimal(freightBale.getContinuationWeight()), 0,
							BigDecimal.ROUND_UP);
					// 总费用=起重+续重*倍数+挂号
					return freightBale.getFirstFreight().add(freightBale.getContinuationFreight().multiply(multiple))
							.add(registrationFee);
				}
			}
		} else {

			/** 小包货物计算流程 **/
			// 优先获取 菜鸟无忧物流-标准 的目的国的计价标准
			ErpProductFreight freight = baseMapper.getFreightTemplateByCountryCode(erpProductExistingFreightRecord.getCountry(),
					erpProductExistingFreightRecord.getType(), erpProductExistingFreightRecord.getWeight(), "菜鸟无忧物流-标准");
			if (freight == null) {
				// 不支持，获取 菜鸟特货专线-标准 的目的国的计价标准
				freight = baseMapper.getFreightTemplateByCountryCode(erpProductExistingFreightRecord.getCountry(), 1,
						erpProductExistingFreightRecord.getWeight(), "菜鸟特货专线-标准");
				if (freight == null) {
					// 不支持，获取获取 CR(哥斯达黎加) 的计价标准
					freight = baseMapper.getFreightTemplateByCountryCode("CR", erpProductExistingFreightRecord.getType(),
							erpProductExistingFreightRecord.getWeight(), null);
				}
			}
			// 按g计算
			BigDecimal smallPackageFreight = freight.getFreight().divide(new BigDecimal("1000"))
					.multiply(new BigDecimal(erpProductExistingFreightRecord.getWeight()));
			return smallPackageFreight.add(freight.getRegistrationFee());
		}
	}
















	public static void main(String[] args) {
//    	String weightSection = "包裹重量50克(不含)-2000克";
//		System.out.println(weightSection.indexOf("-")+1);
//		System.out.println(weightSection.lastIndexOf("克"));
//		System.out.println(weightSection.substring(weightSection.indexOf("-")+1, weightSection.lastIndexOf("克")).trim());
		System.out.println(new BigDecimal("32100").divide(new BigDecimal("100"), 0, BigDecimal.ROUND_DOWN).toString());
	}

	@Override
	public List<ErpProductFreight> countryList() {
		LambdaQueryWrapper<ErpProductFreight> lqw = Wrappers.lambdaQuery();
		lqw.groupBy(ErpProductFreight::getCountry);
		return baseMapper.selectList(lqw);
	}
}
